﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ATCAssistant.Properties;
using WeatherData;

namespace ATCAssistant
{
    public partial class Form1 : Form
    {
        private ICollection<Station> stations;
        private IMetarParser parser;

        public Form1()
        {
            InitializeComponent();

            if (Settings.Default.ExternalTools == null)
                Settings.Default.ExternalTools = new StringDictionary();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.LoadExternalTools();
            this.LoadStations();
        }
        private void LoadStations()
        {
            lstStations.BeginUpdate();
            lstStations.Items.Clear();
            stations = new List<Station>();
            string dataPath = Settings.Default.DataFolderPath;

            // Make sure the stations directory is valid
            if (!Directory.Exists(dataPath))
                Directory.CreateDirectory(dataPath);

            foreach (string file in Directory.GetFiles(dataPath, "*.xml"))
            {
                Station s = Station.Open(file);
                stations.Add(s);

                ListViewItem i = new ListViewItem(s.Name);
                i.SubItems.Add(s.Identifier);
                i.Tag = s;
                lstStations.Items.Add(i);
            }
            lstStations.EndUpdate();
        }
        private void LoadExternalTools()
        {
            // Clear the list
            toolsToolStripMenuItem.DropDownItems.Clear();

            // Add in the management functions
            ToolStripMenuItem add = new ToolStripMenuItem("Add Tool...");
            add.Click += new EventHandler(addToolToolStripMenuItem_Click);
            toolsToolStripMenuItem.DropDownItems.Add(add);

            ToolStripMenuItem manage = new ToolStripMenuItem("Manage Tools...");
            manage.Click += new EventHandler(manageToolsToolStripMenuItem_Click);
            toolsToolStripMenuItem.DropDownItems.Add(manage);

            // Add in the user-defined tools
            if (Settings.Default.ExternalTools.Count > 0)
            {
                ToolStripSeparator sep = new ToolStripSeparator();
                toolsToolStripMenuItem.DropDownItems.Add(sep);
            }

            foreach (DictionaryEntry tool in Settings.Default.ExternalTools)
            {
                ToolStripMenuItem i = new ToolStripMenuItem(tool.Value.ToString());
                i.Tag = tool.Key.ToString();
                i.Click += new EventHandler(ExternalToolItemClick);

                toolsToolStripMenuItem.DropDownItems.Add(i);
            }
        }

        private void ExternalToolItemClick(object sender, EventArgs e)
        {
            ToolStripMenuItem i = sender as ToolStripMenuItem;
            Process.Start(i.Tag.ToString());
        }

        private void lstStations_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstStations.SelectedItems.Count == 1)
            {
                Station station = GetSelectedStation();
                this.RefreshMetar(station);
                this.RefreshRecommendedRunways(station);
                this.RefreshCommunications(station);
            }
        }
        private void addToolToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form addTool = new AddToolDialog();
            if (addTool.ShowDialog(this) == DialogResult.OK)
            {
                Settings.Default.Save();
                this.LoadExternalTools();                
            }
        }

        private void RefreshRecommendedRunways(Station station)
        {
            Cursor.Current = Cursors.WaitCursor;
            lstRecRwy.BeginUpdate();
            lstRecRwy.Items.Clear();
            foreach (RunwayRecommendation rec in RunwayCalculator.RecommendedRunways(station))
            {
                ListViewItem rwyrec = new ListViewItem(rec.Runway.Identifier);
                rwyrec.SubItems.Add(rec.Direction.ToString());
                rwyrec.SubItems.Add(rec.Crosswind.ToString("0.#kt"));
                rwyrec.SubItems.Add(rec.Headwind.ToString("0.#kt"));
                rwyrec.SubItems.Add(rec.Runway.Length.ToString("0ft"));
                lstRecRwy.Items.Add(rwyrec);
            }
            lstRecRwy.EndUpdate();
            Cursor.Current = Cursors.Default;
        }
        private void RefreshCommunications(Station station)
        {
            Cursor.Current = Cursors.WaitCursor;
            lstComms.BeginUpdate();
            lstComms.Items.Clear();

            foreach (Frequency freq in station.Communications)
            {
                ListViewItem i = new ListViewItem(freq.Position.ToString());
                i.SubItems.Add(freq.Callsign);
                i.SubItems.Add(freq.Value.ToString("###.000"));
                i.Tag = freq;
                lstComms.Items.Add(i);
            }

            lstComms.EndUpdate();
            Cursor.Current = Cursors.Default;
        }
        private void RefreshMetar(Station station)
        {
            Cursor.Current = Cursors.WaitCursor;
            this.SetParser();
            rtbMetar.Text = this.parser.Parse(station.GetCurrentMetar());
            Cursor.Current = Cursors.Default;
        }
        private void SetParser()
        {
            if (rdoPlainMetar.Checked)
                this.parser = new PlainLanguageMetarParser();
            else
                this.parser = new RawTextMetarParser();
        }

        private Station GetSelectedStation()
        {
            ListViewItem item = lstStations.SelectedItems[0];
            Station station = item.Tag as Station;
            return station;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void manageToolsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form manageTools = new ManageToolsDialog();
            if (manageTools.ShowDialog(this) == DialogResult.OK)
            {
                Settings.Default.Save();
                this.LoadExternalTools();
            }
        }

        private void reloadStationsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.LoadStations();
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form settings = new SettingsDialog();
            if (settings.ShowDialog(this) == DialogResult.OK)
            {
                this.LoadStations();
                this.LoadExternalTools();
            }
        }        
    }
}
